#ifndef ABSUI_UI_COMMAND_REGISTRY_HPP
#define ABSUI_UI_COMMAND_REGISTRY_HPP

#include "AbsUI/CommonUIConfig.hpp"
#include <string>
#include <map>

class QMenu;
class QToolBar;

namespace AbsUI
{

class UICommand;

// TODO: Test
/// \ingroup AbsUI
/// \brief It manages the commands and other related objects (e.g. menus or toolbars), by associating them with an 
///		(unique) identifier which can be used for retrieval
class COMMON_UI_API UICommandRegistry
{
public:
	virtual ~UICommandRegistry();

	/// \brief It registers a user interface command.
	/// \pre The specified command object is not NULL.
	/// \pre The specified command object is not already registered.
	/// \param cmdID the unique identifier of the command.
	/// \param uiCommand the command to be registered.
	void registerCommand( const std::string& cmdID, UICommand* uiCommand);

	/// \brief It checks whether the specified command identifier is registered or not.
	bool isCommandRegistered( const std::string& cmdID) const;
	
	/// \brief It gets the command associated with the specified identifier.
	/// \pre The specified command identifier is associated with a command.
	/// \{
	UICommand& command( const std::string& cmdID);
	const UICommand& command( const std::string& cmdID) const;
	/// \}

	/// \brief It registers a menu.
	/// \param menuID the identifier of the menu to be registered.
	/// \param pMenu the menu to be registered.
	/// \pre The specified menu is not NULL.
	/// \pre The specified menu identifier is not already used.
	void registerMenu( const std::string& menuID, QMenu* pMenu);

	/// \brief It checks whether the specified menu identifier is registered.
	bool isMenuRegistered( const std::string& menuID) const;

	/// \brief It gets the menu registered with the specified menu identifier.
	/// \pre the specified menu identifier has a menu associated.
	/// \{
	QMenu& menu( const std::string& menuID);
	const QMenu& menu( const std::string& menuID) const;
	/// \}

	/// \brief It registers the specified toolbar with the associated, specified toolbar identifier.
	/// \param toolbarID the identifier of the toolbar to be registered.
	/// \param pToolBar the toolbar to be registered.
	/// \pre the specified toolbar object should not be NULL.
	/// \pre the specified toolbar identifier should not be already registered.
	void registerToolBar( const std::string& toolbarID, QToolBar* pToolBar);
	
	/// \brief It checks whether the toolbar identifier is registered or not.
	bool isToolbarRegistered( const std::string& toolbarID) const;

	/// \brief It gets the toolbar associated with the specified identifier.
	/// \pre The specified toolbar identifier should be registered.
	/// \{
	QToolBar& toolbar( const std::string& toolbarID);
	const QToolBar& toolbar( const std::string& toolbarID) const;
	/// \}

private:
	typedef std::map< std::string, UICommand*> CommandMap;
	typedef std::map< std::string, QMenu*> MenuMap;
	typedef std::map< std::string, QToolBar*> ToolBarMap;
	CommandMap registeredCommands_;
	ToolBarMap registeredToolbars_;
	MenuMap registeredMenus_;
};

} // namespace AbsUI

#endif // ABSUI_UI_COMMAND_REGISTRY_HPP
